unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CPort, ExtCtrls;

type
  TForm1 = class(TForm)
    Comm: TComPort;
    Status: TMemo;
    Send: TButton;
    ComSetting: TButton;
    ComDataPacket1: TComDataPacket;
    Timeout: TTimer;
    SampleTimer: TTimer;
    Connect: TButton;
    GroupBox2: TGroupBox;
    RegCount: TComboBox;
    RegAddr: TEdit;
    MotorAddr: TComboBox;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    ReadReg: TButton;
    ReadCRC: TEdit;
    Label9: TLabel;
    WriteAddr: TComboBox;
    Label10: TLabel;
    Label11: TLabel;
    WriteRegAddr: TEdit;
    Label12: TLabel;
    Label13: TLabel;
    WriteCRC: TEdit;
    WriteReg: TButton;
    WriteRegData: TEdit;
    GroupBox3: TGroupBox;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    RdCoilCnt: TComboBox;
    RdCoilNo: TEdit;
    RdCoilAddr: TComboBox;
    RdCoil: TButton;
    RdCoilCRC: TEdit;
    WrCoilAddr: TComboBox;
    WrCoilNo: TEdit;
    WrCoilCRC: TEdit;
    WrCoil: TButton;
    WrCoilData: TEdit;
    Runbtn: TButton;
    Stopbnt: TButton;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    XSpeed: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label28: TLabel;
    resolution: TComboBox;
    monitor: TCheckBox;
    XDisp: TEdit;
    YDisp: TEdit;
    Polling: TButton;
    WheelSpeed: TEdit;
    SampleTime: TComboBox;
    MaxSpeedEd: TEdit;
    RefSpeedEd: TEdit;
    Label26: TLabel;
    DeltaSpeedEd: TEdit;
    Label27: TLabel;
    DevAddr1: TComboBox;
    Label29: TLabel;
    DevAddr2: TComboBox;
    SetSpeedBnt: TButton;
    RefSpeedEdt: TEdit;
    procedure SendClick(Sender: TObject);
    procedure ComSettingClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ComDataPacket1Packet(Sender: TObject; const Str: string);
    procedure StatusDblClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure TimeoutTimer(Sender: TObject);
    procedure PollingClick(Sender: TObject);
    procedure SampleTimerTimer(Sender: TObject);
    procedure ConnectClick(Sender: TObject);
    procedure ReadRegClick(Sender: TObject);
    procedure WriteRegClick(Sender: TObject);
    procedure RdCoilClick(Sender: TObject);
    procedure WrCoilClick(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure SampleTimeChange(Sender: TObject);
    procedure RunbtnClick(Sender: TObject);
    procedure StopbntClick(Sender: TObject);
    procedure SetSpeedBntClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  COMPORT = 'COM1';

  MOUSE_ADDR = $80;
  POLLING_MOUSE_CMD = ord('a');

  MOTOR_READ_4COIL_CMD = $01;
  MOTOR_WRITE_1COIL_CMD = $05;

  MOTOR_READ_8REG_CMD = $03;
  MOTOR_WRITE_1REG_CMD = $06;
  MOTOR_WRITE_8REG_CMD = $10;

  TURN_ON_MOTOR1_CMD = $80;
  TURN_ON_MOTOR2_CMD = $81;
  TURN_OFF_MOTOR1_CMD = $82;
  TURN_OFF_MOTOR2_CMD = $83;

  SET_SPEED_MOTOR1_CMD = $84;
  SET_SPEED_MOTOR2_CMD = $85;

var
  Form1: TForm1;
  Connected: bool;
  WaitRecFlag : bool;
  pRxBuff: array [0..160] of byte;
  RxCount: integer;
  mode: byte;

  TotalDeltaX: integer;
  TotalDeltaY: integer;
  PollingCount: integer;

  WheelTotal: Integer;

  MaxSpeed: Integer;
  SetSpeed: Integer;
  DeltaSpeed: Integer;
  RefSpeed: Integer;

  RunningFlag : bool;

implementation

{$R *.dfm}


function GetChecksum(pBuff: array of byte; iLen: integer): WORD;
var
  temp: WORD;
  crc: WORD;
  i,j: integer;
begin
  crc := $FFFF;
  for i := 0 to iLen - 1 do
  begin
    crc := ( (crc xor pBuff[i]) or $FF00 ) and (crc or $00FF);
    for j := 0 to 7 do
    begin
      temp := crc and $0001;
      crc := crc shr 1;
      if temp > 0 then
      begin
        crc := crc xor $A001;
      end;
    end;
  end;
  GetChecksum := crc;
end;

Function strtohex(s:string):Byte;
var k1,k2:byte;
begin
k1:=0;
k2:=0;
case S[1] of
'0' : k1:=$00;
'1' : K1:=$10;
'2' : k1:=$20;
'3' : K1:=$30;
'4' : k1:=$40;
'5' : K1:=$50;
'6' : k1:=$60;
'7' : K1:=$70;
'8' : k1:=$80;
'9' : K1:=$90;
'A' : k1:=$A0;
'B' : K1:=$B0;
'C' : k1:=$C0;
'D' : K1:=$D0;
'E' : k1:=$E0;
'F' : K1:=$F0;
end;
case S[2] of
'0' : k2:=$00;
'1' : K2:=$01;
'2' : k2:=$02;
'3' : K2:=$03;
'4' : k2:=$04;
'5' : K2:=$05;
'6' : k2:=$06;
'7' : K2:=$07;
'8' : k2:=$08;
'9' : K2:=$09;
'A' : k2:=$0A;
'B' : K2:=$0B;
'C' : k2:=$0C;
'D' : K2:=$0D;
'E' : k2:=$0E;
'F' : K2:=$0F;
end;
strtohex := k1 or k2;
end;

Function hextostr(i:byte):String;
var k1,k2 : byte;
    sstr,str2 : string;
begin
k1:= i and $F0;
k2:= i and $0F;
case k1 of
$00: sstr:='0';
$10: sstr:='1';
$20: sstr:='2';
$30: sstr:='3';
$40: sstr:='4';
$50: sstr:='5';
$60: sstr:='6';
$70: sstr:='7';
$80: sstr:='8';
$90: sstr:='9';
$A0: sstr:='A';
$B0: sstr:='B';
$C0: sstr:='C';
$D0: sstr:='D';
$E0: sstr:='E';
$F0: sstr:='F';
end;
case k2 of
$00: str2:='0';
$01: str2:='1';
$02: str2:='2';
$03: str2:='3';
$04: str2:='4';
$05: str2:='5';
$06: str2:='6';
$07: str2:='7';
$08: str2:='8';
$09: str2:='9';
$0A: str2:='A';
$0B: str2:='B';
$0C: str2:='C';
$0D: str2:='D';
$0E: str2:='E';
$0F: str2:='F';
end;
hextostr := sstr + str2;
end;


procedure TForm1.SendClick(Sender: TObject);
var pBuff: array [0..16] of byte;
begin
  if Comm.Connected = FALSE then comm.Open;
  pBuff[0] := $80;
  pBuff[1] := ord('y');
  comm.Write(pBuff, 4);
  WaitRecFlag := true;
  RxCount := 0;
end;

procedure TForm1.SetSpeedBntClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  crc : WORD;
  temp : Integer;
begin
  SetSpeed := StrToInt(DeltaSpeedEd.Text);
  if Connected = true then
  begin
    pBuff[0] := DevAddr1.ItemIndex + 1;
    pBuff[1] := MOTOR_WRITE_1REG_CMD;
    pBuff[2] := $00;
    pBuff[3] := $01;
    temp := SetSpeed mod $10000;
    pBuff[4] := temp div $100;
    pBuff[5] := temp mod $100;
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := SET_SPEED_MOTOR1_CMD;
  end;
end;

procedure TForm1.RdCoilClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  str: string;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := RdCoilAddr.ItemIndex + 1;
    pBuff[1] := MOTOR_READ_4COIL_CMD;
    str := RdCoilNo.Text;
    pBuff[2] := StrToHex(str[1] + str[2]);
    pBuff[3] := StrToHex(str[3] + str[4]);
    pBuff[4] := $00;
    pBuff[5] := RdCoilCnt.ItemIndex + 1;
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;
    RdCoilCRC.Text := HexToStr(pBuff[6]) + HexToStr(pBuff[7]);

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := MOTOR_READ_4COIL_CMD;
  end;
end;

procedure TForm1.ReadRegClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  str: string;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := MotorAddr.ItemIndex + 1;
    pBuff[1] := MOTOR_READ_8REG_CMD;
    str := RegAddr.Text;
    pBuff[2] := StrToHex(str[1] + str[2]);
    pBuff[3] := StrToHex(str[3] + str[4]);
    pBuff[4] := $00;
    pBuff[5] := RegCount.ItemIndex + 1;
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;
    ReadCRC.Text := HexToStr(pBuff[6]) + HexToStr(pBuff[7]);

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := MOTOR_READ_8REG_CMD;
  end;
end;

procedure TForm1.RunbtnClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  crc : WORD;
begin
  if Connected = true then
  begin
    MaxSpeed := StrToInt(MaxSpeedEd.Text);
    RefSpeed := StrToInt(RefSpeedEd.Text);
    DeltaSpeed := StrToInt(DeltaSpeedEd.Text);

    pBuff[0] := DevAddr1.ItemIndex + 1;
    pBuff[1] := MOTOR_WRITE_1COIL_CMD;
    pBuff[2] := $00;
    pBuff[3] := $00;
    pBuff[4] := $FF;
    pBuff[5] := $00;
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := TURN_ON_MOTOR1_CMD;
  end
  else
  begin
    ShowMessage('Connect comport first!');
  end;
end;

procedure TForm1.WrCoilClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  str: string;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := WrCoilAddr.ItemIndex + 1;
    pBuff[1] := MOTOR_WRITE_1COIL_CMD;
    str := WrCoilNo.Text;
    pBuff[2] := StrToHex(str[1] + str[2]);
    pBuff[3] := StrToHex(str[3] + str[4]);
    str := WrCoilData.Text;
    pBuff[4] := StrToHex(str[1] + str[2]);
    pBuff[5] := StrToHex(str[3] + str[4]);
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;
    WrCoilCRC.Text := HexToStr(pBuff[6]) + HexToStr(pBuff[7]);

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := MOTOR_WRITE_1COIL_CMD;
  end;
end;

procedure TForm1.WriteRegClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  str: string;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := WriteAddr.ItemIndex + 1;
    pBuff[1] := MOTOR_WRITE_1REG_CMD;
    str := WriteRegAddr.Text;
    pBuff[2] := StrToHex(str[1] + str[2]);
    pBuff[3] := StrToHex(str[3] + str[4]);
    str := WriteRegData.Text;
    pBuff[4] := StrToHex(str[1] + str[2]);
    pBuff[5] := StrToHex(str[3] + str[4]);
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;
    WriteCRC.Text := HexToStr(pBuff[6]) + HexToStr(pBuff[7]);

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := MOTOR_WRITE_1REG_CMD;
  end;
end;

procedure TForm1.ComDataPacket1Packet(Sender: TObject; const Str: string);
var
  i: integer;
begin
  if WaitRecFlag = true then
  begin
    Timeout.Enabled := false;

    for I := 1 to Length(str) do
    begin
      pRxBuff[RxCount] := ord(str[i]);
      inc(RxCount);
    end;

    Timeout.Enabled := true;
  end;
end;

procedure TForm1.ComSettingClick(Sender: TObject);
begin
  comm.ShowSetupDialog;
end;

procedure TForm1.ConnectClick(Sender: TObject);
begin
  if comm.Connected = true then
  begin
    comm.Close;
    Connected := false;
    connect.Caption := 'Open COM';
  end
  else
  begin
    comm.Open;
    Connected := true;
    connect.Caption := 'Close COM';
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if comm.Connected = true then comm.Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Connected := false;
  WaitRecFlag := false;
  PollingCount := 0;
  comm.Port := COMPORT;

  RunningFlag := false;
end;

procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  if (WheelDelta > 0) then
  begin
    WheelTotal := WheelTotal + WheelDelta;
  end;
end;

procedure TForm1.PollingClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := MOUSE_ADDR;
    pBuff[1] := POLLING_MOUSE_CMD;
    crc := GetChecksum(pBuff, 2);
    pBuff[2] := crc div $100;
    pBuff[3] := crc mod $100;
    comm.Write(pBuff, 4);
    WaitRecFlag := true;
    RxCount := 0;
    mode := POLLING_MOUSE_CMD;
  end
  else
  begin
    XDisp.Text := '';
    YDisp.Text := '';
  end;
end;

procedure TForm1.SampleTimeChange(Sender: TObject);
begin
  SampleTimer.Interval := (SampleTime.ItemIndex + 1) * 1000;
end;

procedure TForm1.SampleTimerTimer(Sender: TObject);
var
  SetSpeed, RefSpeed, CurSpeed : Integer;
begin
  CurSpeed := WheelTotal div 120;
  WheelSpeed.Text := IntToStr(CurSpeed);
  WheelTotal := 0;
  if RunningFlag = True then
  begin
    RefSpeed := StrToInt(RefSpeedEdt.Text);
    SetSpeed := StrToInt(DeltaSpeedEd.Text);
    if CurSpeed > RefSpeed + 4 then
    begin
      SetSpeed := SetSpeed - 10;
      DeltaSpeedEd.Text := IntToStr(SetSpeed);
      SetSpeedBntClick(self);
    end
    else if CurSpeed < RefSpeed - 4 then
    begin
      SetSpeed := SetSpeed + 10;
      DeltaSpeedEd.Text := IntToStr(SetSpeed);
      SetSpeedBntClick(self);
    end;
  end;
end;

procedure TForm1.StatusDblClick(Sender: TObject);
begin
  Status.Clear;
end;

procedure TForm1.StopbntClick(Sender: TObject);
var
  pBuff: array [0..16] of byte;
  crc : WORD;
begin
  if Connected = true then
  begin
    pBuff[0] := DevAddr1.ItemIndex + 1;
    pBuff[1] := MOTOR_WRITE_1COIL_CMD;
    pBuff[2] := $00;
    pBuff[3] := $00;
    pBuff[4] := $00;
    pBuff[5] := $00;
    crc := GetChecksum(pBuff, 6);
    pBuff[6] := crc mod $100;
    pBuff[7] := crc div $100;

    comm.Write(pBuff, 8);
    WaitRecFlag := true;
    RxCount := 0;
    mode := TURN_OFF_MOTOR1_CMD;
  end
  else
  begin
    ShowMessage('Connect COM port first');
  end;
end;

procedure TForm1.TimeoutTimer(Sender: TObject);
var
  i: integer;
  crc : WORD;
  s: String;

  DataByteCnt: byte;
  RegCnt: integer;
  pBuff: array [0..16] of byte;
  temp : WORD;
begin
  Timeout.Enabled := false;
  WaitRecFlag := false;

  case mode of
  POLLING_MOUSE_CMD:
    begin
      crc := GetChecksum(pRxBuff, 7);
      if (pRxBuff[7] = (crc div $100)) and (pRxBuff[8] = (crc mod $100)) then
      begin
        TotalDeltaX := TotalDeltaX + pRxBuff[3]*$100 + pRxBuff[4];
        TotalDeltaY := TotalDeltaY + pRxBuff[5]*$100 + pRxBuff[6];
      end;
      if PollingCount = 5 then
      begin
        PollingCount := 0;
        XDisp.Text := IntToStr(TotalDeltaX div 4);
        YDisp.Text := IntToStr(TotalDeltaY div 4);
        TotalDeltaX := 0;
        TotalDeltaY := 0;
      end;
    end;

  MOTOR_READ_4COIL_CMD:
    begin
      if (pRxBuff[0] = RdCoilAddr.ItemIndex+1) and (pRxBuff[1] = MOTOR_READ_4COIL_CMD) then
      begin
        DataByteCnt := pRxBuff[2];
        RegCnt := 1;

        crc := GetChecksum(pRxBuff, DataByteCnt + 3);
        if (pRxBuff[DataByteCnt+4] = (crc div $100)) and (pRxBuff[DataByteCnt+3] = (crc mod $100)) then
        begin
          i := 3;
          while DataByteCnt > 0 do
          begin
            Status.Lines.Add('Coil Data ' + inttostr(RegCnt) + ': ' + IntToHex(pRxBuff[i], 2));
            DataByteCnt := DataByteCnt - 1;
            i := i + 1;
            inc(RegCnt);
          end;
        end;
      end;
    end;

  MOTOR_READ_8REG_CMD:
    begin
      if (pRxBuff[0] = MotorAddr.ItemIndex+1) and (pRxBuff[1] = MOTOR_READ_8REG_CMD) then
      begin
        DataByteCnt := pRxBuff[2];
        RegCnt := 1;

        crc := GetChecksum(pRxBuff, DataByteCnt + 3);
        if (pRxBuff[DataByteCnt+4] = (crc div $100)) and (pRxBuff[DataByteCnt+3] = (crc mod $100)) then
        begin
          i := 3;
          while DataByteCnt > 0 do
          begin
            Status.Lines.Add('Register Data ' + inttostr(RegCnt) + ': ' + IntToHex(pRxBuff[i], 2) + IntToHex(pRxBuff[i+1], 2));
            DataByteCnt := DataByteCnt - 2;
            i := i + 2;
            inc(RegCnt);
          end;
        end;
      end;
    end;

  MOTOR_WRITE_1REG_CMD:
    begin
      if (pRxBuff[0] = MotorAddr.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1REG_CMD) then
      begin
      Status.Lines.Add('Write Register OK');
      end;
    end;

  SET_SPEED_MOTOR1_CMD:
    begin
      if (pRxBuff[0] = DevAddr1.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1REG_CMD) then
      begin
        pBuff[0] := DevAddr2.ItemIndex + 1;
        pBuff[1] := MOTOR_WRITE_1REG_CMD;
        pBuff[2] := $00;
        pBuff[3] := $01;
        temp := SetSpeed mod $10000;
        pBuff[4] := temp div $100;
        pBuff[5] := temp mod $100;
        crc := GetChecksum(pBuff, 6);
        pBuff[6] := crc mod $100;
        pBuff[7] := crc div $100;

        comm.Write(pBuff, 8);
        WaitRecFlag := true;
        RxCount := 0;
        mode := SET_SPEED_MOTOR2_CMD;
      end;
    end;

  SET_SPEED_MOTOR2_CMD:
    begin
      if (pRxBuff[0] = DevAddr1.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1REG_CMD) then
      begin
        Status.Lines.Add('Change speed OK');
      end;
    end;

  TURN_ON_MOTOR1_CMD:
    begin
      if (pRxBuff[0] = DevAddr1.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1COIL_CMD) then
      begin
        pBuff[0] := DevAddr2.ItemIndex + 1;
        pBuff[1] := MOTOR_WRITE_1COIL_CMD;
        pBuff[2] := $00;
        pBuff[3] := $00;
        pBuff[4] := $FF;
        pBuff[5] := $00;
        crc := GetChecksum(pBuff, 6);
        pBuff[6] := crc mod $100;
        pBuff[7] := crc div $100;

        comm.Write(pBuff, 8);
        WaitRecFlag := true;
        RxCount := 0;
        mode := TURN_ON_MOTOR2_CMD;
      end;
    end;

  TURN_ON_MOTOR2_CMD:
    begin
      if (pRxBuff[0] = DevAddr2.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1COIL_CMD) then
      begin
        Status.Lines.Add('Turn on OK');
        RunningFlag := true;
      end;
    end;

  TURN_OFF_MOTOR1_CMD:
    begin
      if (pRxBuff[0] = DevAddr1.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1COIL_CMD) then
      begin
        pBuff[0] := DevAddr2.ItemIndex + 1;
        pBuff[1] := MOTOR_WRITE_1COIL_CMD;
        pBuff[2] := $00;
        pBuff[3] := $00;
        pBuff[4] := $00;
        pBuff[5] := $00;
        crc := GetChecksum(pBuff, 6);
        pBuff[6] := crc mod $100;
        pBuff[7] := crc div $100;

        comm.Write(pBuff, 8);
        WaitRecFlag := true;
        RxCount := 0;
        mode := TURN_OFF_MOTOR2_CMD;
      end;
    end;

  TURN_OFF_MOTOR2_CMD:
    begin
      if (pRxBuff[0] = DevAddr2.ItemIndex+1) and (pRxBuff[1] = MOTOR_WRITE_1COIL_CMD) then
      begin
        Status.Lines.Add('Turn off OK');
        RunningFlag := false;
      end;
    end

  else
  begin
    Status.Lines.Add(IntToHex(RxCount, 4));

    s := '';
    for I := 0 to RxCount - 1 do
    begin
      s := s + IntToHex(pRxBuff[i], 2) +' ';
    end;
    Status.Lines.Add(s);
  end;
  end;
  RxCount := 0;
end;

end.

